package com.fengye.webflux.mongo.service;

import com.fengye.webflux.model.Article;
import com.fengye.webflux.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.ExampleMatcher;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import static org.springframework.data.domain.ExampleMatcher.GenericPropertyMatchers.startsWith;

/**
 * {@link Mono#log()} log()方法:该方法使用了Reactor框架中的日志工具类.
 * <br>
 * 通过添加log()方法,在执行数据操作时就会获取Reactor框架中对数据的详细操作日志信息.
 * @author sky
 * @date 2021年06月01日 1:48 下午
 */
@Service
public class ArticleService {
    @Autowired
    private ArticleRepository articleRepository;

    public Mono<Article> save(Article article){
        return articleRepository.save(article);
    }

    public Mono<Article> findOne(String id){
        return articleRepository.findById(id).log("findOneArticle");
    }

    public Flux<Article> findAll(){
        return articleRepository.findAll();
    }

    public Mono<Void> delete(String id){
        return articleRepository.deleteById(id).log("deleteOneArticle");
    }

    /**
     * {@link org.springframework.data.repository.query.ReactiveQueryByExampleExecutor}
     * <br>
     * 首先构建一个ExampleMatcher用于初始化匹配规则,然后通过传入一个Author对象实例和ExampleMatcher实例构建一个Example对象
     * <br>
     * 最后通过ReactiveQueryByExampleExecutor接口中的findAll()方法实现了QueryByExample机制
     * @param author 作者信息
     * @return reactor.core.publisher.Flux<com.fengye.webflux.model.Article>
     */
    public Flux<Article> findByAuthor(String author){
        Article article = new Article();
        article.setAuthor(author);

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withIgnoreCase()
                .withMatcher(author, startsWith())
                .withIncludeNullValues();

        Example<Article> example = Example.of(article, matcher);

        Flux<Article> articles = articleRepository.findAll(example)
                .log("findByAuthor");

        return articles;
    }
}
